package com.example.fang.demodruid.config.shiro.realm;

import com.example.fang.demodruid.config.shiro.ShiroUtils;
import com.example.fang.demodruid.config.shiro.service.SysLoginService;
import com.example.fang.demodruid.entity.SysUser;
import com.example.fang.demodruid.exception.user.*;
import com.example.fang.demodruid.service.ISysMenuService;
import com.example.fang.demodruid.service.ISysRoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @describe: 自定义Realm 处理登录 权限
 * @author:01410843
 * @Date 2022/7/15 18:04
 **/
public class UserRealm extends AuthorizingRealm {
    private static final Logger log = LoggerFactory.getLogger(UserRealm.class);

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private SysLoginService loginService;

    /**
     * @Author 01410843
     * @Description 授权
     * @Date 9:50 2022/7/18
     * @Param [principalCollection]
     * @return org.apache.shiro.authz.AuthorizationInfo
     **/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SysUser user = ShiroUtils.getSysUser();
        // 角色列表
        Set<String> roles = new HashSet<String>();
        // 功能列表
        Set<String> menus = new HashSet<String>();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 管理员拥有所有权限
        if (user.isAdmin()){
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        }else{
            roles = roleService.selectRoleKeys(user.getUserId());
            menus = menuService.selectPermsByUserId(user.getUserId());
            // 角色加入AuthorizationInfo认证对象
            info.setRoles(roles);
            // 权限加入AuthorizationInfo认证对象
            info.setStringPermissions(menus);
        }
        return null;
    }

    /**
     * @Author 01410843
     * @Description 登录认证
     * @Date 9:50 2022/7/18
     * @Param [authenticationToken]
     * @return org.apache.shiro.authc.AuthenticationInfo
     **/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        String password = "";
        if (upToken.getPassword() != null) {
            password = new String(upToken.getPassword());
        }
        SysUser user = null;
        try {
            user = loginService.login(username, password);
        }catch (CaptchaException e){
            throw new AuthenticationException(e.getMessage(), e);
        } catch (UserNotExistsException e){
            throw new UnknownAccountException(e.getMessage(), e);
        }catch (UserPasswordNotMatchException e){
            throw new IncorrectCredentialsException(e.getMessage(), e);
        }catch (UserPasswordRetryLimitExceedException e){
            throw new ExcessiveAttemptsException(e.getMessage(), e);
        } catch (UserBlockedException e){
            throw new LockedAccountException(e.getMessage(), e);
        } catch (RoleBlockedException e){
            throw new LockedAccountException(e.getMessage(), e);
        } catch (Exception e){
            log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
            throw new AuthenticationException(e.getMessage(), e);
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }
}
